package com.shop.cereshop.agent.service.stock.impl;

import com.shop.cereshop.agent.service.product.AgentProductSkuService;
import com.shop.cereshop.agent.service.stock.AgentStockService;
import com.shop.cereshop.commons.cache.constants.CacheKeyConstants;
import com.shop.cereshop.commons.domain.order.CereAgentOrderProduct;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * @description: TODO
 * @author lx
 * @date 2025/11/11 16:14
 * @version 1.0
 */
@Slf4j
@Service
public class AgentStockServiceImpl implements AgentStockService {

  @Resource
  private RedissonClient redissonClient;

  @Resource
  private AgentProductSkuService agentProductSkuService;

  public AgentStockServiceImpl(RedissonClient redissonClient) {
    this.redissonClient = redissonClient;
  }

  @Override
  public void rollbackStockByList(List<CereAgentOrderProduct> list) {
    for (CereAgentOrderProduct cereAgentOrderProduct : list) {
      rollbackStock(cereAgentOrderProduct);
    }
  }

  private void rollbackStock(CereAgentOrderProduct cereAgentOrderProduct) {
    String lockKey = "";
    RLock lock = null;
    try {
      // 获取订单商品信息
      Long skuId = cereAgentOrderProduct.getSkuId();
      Integer buyNumber = cereAgentOrderProduct.getNumber();

      // 1、加锁
      lockKey = CacheKeyConstants.SKU_STOCK_LOCK_KEY + skuId;
      lock = redissonClient.getLock(lockKey);
      lock.lock();

      // 2、恢复Redis中的SKU库存缓存
      String skuCacheKey = CacheKeyConstants.SKU_STOCK_PREFIX + skuId;
      RBucket<Integer> bucket = redissonClient.getBucket(skuCacheKey);
      if (bucket.isExists()) {
        Integer currentStock = bucket.get();
        if (currentStock != null) {
          bucket.set(currentStock + buyNumber);
        }
      }

      // 3、恢复数据库中的SKU库存
      agentProductSkuService.rollbackStock(skuId, buyNumber);

      log.info("代理商SKU库存恢复成功，skuId:{},恢复数量:{}", skuId, buyNumber);
    } finally {
      if (lock != null) {
        lock.unlock();
      }
    }
  }
}
